<?php

namespace yak\layui\controllers;

use Yii;
use yak\layui\helper\RbacHelper;
use yak\layui\models\rbac\AssignForm;
use yak\layui\models\rbac\AuthItem;
use yak\layui\search\AuthItemSearch;
use yii\helpers\ArrayHelper;
use yii\web\NotFoundHttpException;

/**
 * Class RbacController
 * @package yak\layui\controllers
 */
class RbacController extends BaseController
{
    protected $verbs = [
        'delete-permission' => ['POST'],
        'delete-role' => ['POST'],
    ];

    protected $onlyList = [
        'permissions',
        'roles',
    ];

    protected $onlyCreator = [
        'permission-create',
        'role-create',
    ];

    protected $onlyEditor = [
        'permission-update',
        'role-update'
    ];

    public function actionPermissions()
    {
        return $this->authItems(AuthItem::TYPE_PERMISSION, 'permission/index');
    }

    public function actionPermissionCreate()
    {
        $this->layout = 'blank';
        $model = new AuthItem(['type' => AuthItem::TYPE_PERMISSION]);
        return $this->render('permission/_form', [
            'model' => $model,
            'ajaxOptions' => [
                'modelClass' => $this->ajaxHeaderClass($model),
            ]
        ]);
    }

    public function actionPermissionUpdate($name)
    {
        $this->layout = 'blank';
        $model = $this->findModel(['name' => $name, 'type' => AuthItem::TYPE_PERMISSION]);

        return $this->render('permission/_form', [
            'model' => $model,
            'ajaxOptions' => [
                'modelClass' => $this->ajaxHeaderClass($model),
                'condition' => ['name' => $name, 'type' => AuthItem::TYPE_PERMISSION]
            ]
        ]);
    }

    public function actionPermissionView($name)
    {
        return $this->renderPartial('permission/_view', [
            'model' => $this->findModel(['name' => $name, 'type' => AuthItem::TYPE_PERMISSION]),
        ]);
    }

    public function actionPermissionDelete($name)
    {
        $auth = Yii::$app->authManager;
        $obj = $auth->getPermission($name);
        $auth->remove($obj);
        return $this->ajaxSuccess();
    }

    public function actionPermissionBatchDelete()
    {
        $data = Yii::$app->request->post('Data', []);
        $names = ArrayHelper::getValue($data, 'names', []);
        $auth = Yii::$app->authManager;
        foreach ($names as $name) {
            $obj = $auth->getPermission($name);
            $auth->remove($obj);
        }
        return $this->ajaxSuccess();
    }

    public function actionRoles()
    {
        return $this->authItems(AuthItem::TYPE_RULE, 'roles/index');
    }

    public function actionRoleCreate()
    {
        $this->layout = 'blank';
        $model = new AuthItem(['type' => AuthItem::TYPE_RULE]);
        return $this->render('roles/_form', [
            'model' => $model,
            'ajaxOptions' => [
                'modelClass' => $this->ajaxHeaderClass($model),
            ]
        ]);
    }

    public function actionRoleUpdate($name)
    {
        $this->layout = 'blank';
        $model = $this->findModel(['name' => $name, 'type' => AuthItem::TYPE_RULE]);

        return $this->render('roles/_form', [
            'model' => $model,
            'ajaxOptions' => [
                'modelClass' => $this->ajaxHeaderClass($model),
                'condition' => ['name' => $name, 'type' => AuthItem::TYPE_RULE]
            ]
        ]);
    }

    public function actionRoleView($name)
    {
        return $this->renderPartial('roles/_view', [
            'model' => $this->findModel(['name' => $name, 'type' => AuthItem::TYPE_RULE]),
        ]);
    }

    public function actionRoleDelete($name)
    {
        $auth = Yii::$app->authManager;
        $obj = $auth->getRole($name);
        $auth->remove($obj);
        return $this->ajaxSuccess();
    }

    public function actionRoleBatchDelete()
    {
        $data = Yii::$app->request->post('Data', []);
        $names = ArrayHelper::getValue($data, 'names', []);
        $auth = Yii::$app->authManager;
        foreach ($names as $name) {
            $obj = $auth->getRole($name);
            $auth->remove($obj);
        }
        return $this->ajaxSuccess();
    }

    /**
     * @param $type
     * @param $view
     * @return string
     */
    protected function authItems($type, $view)
    {
        $searchModel = new AuthItemSearch();
        $searchModel->type = $type;
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render($view, [
            'searchModel' => $searchModel, 'dataProvider' => $dataProvider,
        ]);
    }

    public function actionAuth($name)
    {
        if (Yii::$app->request->isPost) {
            $model = new AssignForm();
            if ($model->load(Yii::$app->request->post(), '') && $model->setChildrenToRole($name)) {
                Yii::$app->session->setFlash('success', '<b>权限分配成功</b>');
                return $this->redirect(['roles']);
            }
        }

        return $this->render('roles/auth', [
            'permissions' => AssignForm::permissionsLayuiTreeList(),
            'roles' => AssignForm::rolesTreeList($name),
            'name' => $name
        ]);
    }

    public function actionAutoPermissions($dir, $module, $except = ['base'])
    {
        $dir = Yii::getAlias($dir);
        RbacHelper::autoPermissions($dir, $module, $except);
        return $this->ajaxSuccess();
    }

    /**
     * Finds the AuthItem model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param array $condition
     * @return AuthItem the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($condition)
    {
        if (($model = AuthItem::findOne($condition)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }

}
